/*
Player.h
声明玩家对象
*/

#ifndef PLAYER_H
#define PLAYER_H

#include <string>
#include <vector>
#include <queue>
#include <math.h>
#include <unordered_map>
#include <LevelAction.h>

using namespace std;

/// @brief 方向向量信息
struct Vector2 {
    float x;
    float y;
    float returnLength();
    void normalize();
    void add(Vector2 other);
    void sub(Vector2 other);
    void mult(float ratio);
    float distance(const Vector2& other);
    void turn(const float turnAngle);
};

class Player;

/// @brief 武器
struct Weapon {
    string bulletType = "normal_bullet";
    int ammo = 1;
    int maxAmmo = 1;
    float coldDown = 0.5f;
    float maxColdDown = 0.5f;

    void fillWeapon(string bulletType, Player *targetPlayer);
    void fillWeapon(string bulletType, Player *targetPlayer, queue<LevelAction> &responseBuffer);
};

/// @brief 玩家
class Player {
public:
    string playerName;
    string uuid;
    Vector2 pos;
    Vector2 velocity;
    // 基本信息

    int killCount = 0;
    int deathCount = 0;
    int score = 0;
    // 对局信息

    /// @brief 该玩家是否需要同步全局参量
    bool requireSync = true;

    bool keyWPressed = false;
    bool keyAPressed = false;
    bool keySPressed = false;
    bool keyDPressed = false;

    Vector2 mousePos;
    float angle = 0;

    bool mouseLeftPressed = false;
    bool mouseRightPressed = false;
    // 操作信息

    float immuneTime = 3.0f;

    float moveStrength = 6500.0f;
    float friction = 3000.0f;
    float frictionRate = 10.0f;

    float grazeVelocity = 2400.0f;
    float grazeColdDown = 0.8f;
    float grazeMaxColdDown = 0.8f;

    float hitPoints = 100.0f;

    float recovery = 0.0f;
    float maxRecovery = 10.0f;

    Weapon weapon;
    // 状态信息

    /// @brief 填充玩家信息
    void fillPlayer(string playerName, string uuid, Vector2 pos, Weapon weapon);
    /// @brief 更新玩家信息
    void Update(const float rate, queue<LevelAction>& responseBuffer);
    /// @brief 给予玩家随机武
    void randomWeapon(queue<LevelAction> &responseBuffer);
    /// @brief 打印玩家信息
    void printPlayerInfo();
};

struct YoukaiInfos {
    float fireMaxColdDown = 0.8f;
    float hitPoints = 50.0f;
    float lifeTime = 10.0f;
};

/// @brief 妖怪（NPC敌对单位）
class Youkai {
public:
    string youkaiType;
    string uuid;
    Vector2 pos;
    Vector2 velocity;
    // 基本信息

    /// @brief 这个妖怪的信息是否需要被同步到全局
    bool requireSync = true;

    Vector2 mousePos;
    float angle = 0;

    float existTime = 0.0f;

    float fireColdDown = 0.0f;
    float fireMaxColdDown = 0.8f;

    float moveStrength = 6500.0f;
    float friction = 0.0f;
    float frictionRate = 0.0f;

    float hitPoints = 100.0f;
    float lifeTime = 10.0f;
    // 状态信息

    /// @brief 填充NPC信
    void fillYoukai(string youkaiType, string uuid, Vector2 pos);
    /// @brief 更新NPC信息
    void Update(const float rate, queue<LevelAction> &responseBuffer);
    /// @brief 打印NPC信息
    void printYoukaiInfo();
};

/// @brief 获取某个NPC周围最近的玩家
/// @return 玩家对象指针
Player* getNearestPlayer(Youkai* youkai, unordered_map<string, Player>& players);

#endif